import cacheCreate from "../../cache/index.js";
import defaultConfig from "../config.js";
import aListener from "./aListener.js";

const dictMap = "ingrun_dict_data";
const selecting = new Map();
function formatDict(labelKey = "label", valueKey = "value", list) {
  return list.map((i) => {
    return {
      label: i[labelKey],
      value: i[valueKey],
      data: i,
    };
  });
}

export default class IRDict {
  constructor(vue, config = defaultConfig) {
    this._vue = vue;
    this._config = config;
    this._cache = cacheCreate(this._vue);
    this._cache.set(dictMap, {});
  }

  addDictItme = (dictKey, dictList = [], log = false) => {
    const config = this._config;
    this._vue.set(
      this._cache.get(dictMap),
      dictKey,
      formatDict(config.labelKey, config.valueKey, dictList)
    );

    aListener.emit("setData:" + dictKey, this.getDictList(dictKey));
    if (log) {
      console.log(this._cache.get(dictMap));
    }
  };

  getDictList = (dictKey) => {
    const list = this._cache.get(dictMap)[dictKey];
    if (!list) {
      this.addDictItme(dictKey, []);
      const config = this._config;
      config.remoteMethod && config.remoteMethod(dictKey, this.addDictItme);
      return this.getDictList(dictKey);
    }
    return list;
  };

  getDictListAsync = (dictKey, timeout = 6000) => {
    return new Promise((resolve, reject) => {
      const list = this._cache.get(dictMap)[dictKey];
      const config = this._config;
      if (list) {
        resolve(list);
        return;
      } else if (!list && config.remoteMethod) {
        if (!selecting.get(dictKey)) {
          selecting.set(dictKey, "1");
          config.remoteMethod(dictKey, this.addDictItme);
        }
        aListener.once("setData:" + dictKey, (res) => {
          selecting.delete(dictKey);
          resolve(res);
        });

        setTimeout(() => {
          selecting.delete(dictKey);
          reject("callback timeout: " + dictKey);
        }, timeout);
      }
    });
  };

  getDictLabelAsync = (dictKey, dictValue, timeout = 6000) => {
    return new Promise((resolve, rej) => {
      this.getDictListAsync(dictKey, timeout)
        .then((res) => {
          const item = res.find((i) => i.value == dictValue);
          item ? resolve(item.label) : resolve("-");
        })
        .catch((e) => rej(e));
    });
  };

  getDictLabel = (dictKey, dictValue) => {
    const list = this.getDictList(dictKey);
    const item = list.find((i) => i.value == dictValue);
    if (item) {
      return item.label;
    }
    return "-";
  };
}
